package com.ruicar.afs.cloud.afscase.loanactivaterules.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.afscase.approvemakelabel.service.ApproveMakeLabelService;
import com.ruicar.afs.cloud.afscase.autoaudit.service.IRuleAtomDataService;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelBaseInfo;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelRiskInfo;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelAffiliatedUnitsService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelBaseInfoService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelRiskInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCarInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCarStyleDetail;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseChannelInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.*;
import com.ruicar.afs.cloud.afscase.loanactivatepool.entity.LoanActivatePool;
import com.ruicar.afs.cloud.afscase.loanactivatepool.service.LoanActivateService;
import com.ruicar.afs.cloud.afscase.loanactivatepool.vo.LoanActivatePoolListVO;
import com.ruicar.afs.cloud.afscase.loanactivatepool.vo.LoanActivatePoolVO;
import com.ruicar.afs.cloud.afscase.loanactivaterules.entity.LoanActivateRules;
import com.ruicar.afs.cloud.afscase.loanactivaterules.mapper.LoanActivateRulesMapper;
import com.ruicar.afs.cloud.afscase.loanactivaterules.service.LoanActivateRulesService;
import com.ruicar.afs.cloud.afscase.loanactivaterules.vo.LoanActivateTrialVO;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.rules.entity.AfsRuleInfo;
import com.ruicar.afs.cloud.bizcommon.rules.service.AfsRuleInfoService;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.CostTypeEnum;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.WhetherEnum;
import com.ruicar.afs.cloud.common.rules.RuleHelper;
import com.ruicar.afs.cloud.common.rules.constants.RuleRunEnum;
import com.ruicar.afs.cloud.common.rules.dto.RuleRunResult;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author yk.Li
 * @description 激活规则配置实现类
 * @date 2020/5/16 17:24
 */
@Service
@AllArgsConstructor
@Data
@Slf4j
public class LoanActivateRulesServiceImpl extends ServiceImpl<LoanActivateRulesMapper, LoanActivateRules> implements LoanActivateRulesService {

    private AfsRuleInfoService afsRuleInfoService;
    private IRuleAtomDataService ruleAtomDataService;
    private ApproveMakeLabelService approveMakeLabelService;
    private CaseBaseInfoService caseBaseInfoService;
    private CaseCarInfoService caseCarInfoService;
    private CaseCostInfoService caseCostInfoService;
    private ChannelRiskInfoService channelRiskInfoService;
    private ChannelBaseInfoService channelBaseInfoService;
    private ChannelAffiliatedUnitsService channelAffiliatedUnitsService;
    private CaseChannelInfoService caseChannelInfoService;
    private CaseCarStyleDetailService carStyleDetailInfoService;
    private LoanActivateService loanActivateService;

    @Override
    public Boolean hitRules(String applyNo, String ruleId) {
        Boolean runResult = Boolean.FALSE;
        if (StringUtils.isBlank(applyNo)) {
            return null;
        }
        JSONObject params = new JSONObject();
        CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
                .eq(CaseBaseInfo::getApplyNo, applyNo));
        if (ObjectUtils.isNotEmpty(caseBaseInfo)) {
            /**业务类型*/
            String businessType = caseBaseInfo.getBusinessType();
            params.put("businessType", businessType);

            /**车辆类型*/
            String carType = caseBaseInfo.getCarType();
            params.put("carType", carType);

            /**车辆属性*/
            String carNature = caseBaseInfo.getCarNature();
            params.put("carNature", carNature);

            /**运营方式*/
            String operateWay = caseBaseInfo.getOperateWay();
            params.put("operateWay", operateWay);

            /**挂靠方式*/
            String affiliatedWay = caseBaseInfo.getAffiliatedWay();
            params.put("affiliatedWay", affiliatedWay);

            /**金融产品*/
            Long productId = caseBaseInfo.getProductId();
            params.put("productId", productId.toString());

            /**自动标识*/
            String automaticTag = caseBaseInfo.getAutomaticTag();
            params.put("automaticTag", automaticTag);
        }
        CaseChannelInfo caseChannelInfo = caseChannelInfoService.getOne(Wrappers.<CaseChannelInfo>query().lambda()
                .eq(CaseChannelInfo::getApplyNo, applyNo));
        if (ObjectUtils.isNotEmpty(caseChannelInfo)) {
            /**经销商名称*/
            String dealerName = caseChannelInfo.getDealerName();
            params.put("dealerName", dealerName);
            /**---------------------------------   渠道风控信息    --------------------------------**/
            ChannelBaseInfo channelBaseInfo = channelBaseInfoService.getOne(Wrappers.<ChannelBaseInfo>query().lambda()
                    .eq(ChannelBaseInfo::getChannelCode, caseChannelInfo.getDealerNo()));
            if (null != channelBaseInfo) {
                ChannelRiskInfo channelRiskInfo = channelRiskInfoService.getOne(Wrappers.<ChannelRiskInfo>query().lambda()
                        .eq(StringUtils.isNotBlank(caseChannelInfo.getDealerNo()), ChannelRiskInfo::getChannelId, channelBaseInfo.getChannelId())
                        .eq(StringUtils.isNotBlank(channelBaseInfo.getBusinessType()), ChannelRiskInfo::getBusinessType, channelBaseInfo.getBusinessType()));
                if (ObjectUtils.isNotEmpty(channelRiskInfo)) {
                    /**优质等级*/
                    String qualityGrade = channelRiskInfo.getQualityGrade();
                    params.put("qualityGrade", qualityGrade);
                    /**合作商评级*/
                    params.put("channelGrade", channelRiskInfo.getChannelGrade());
                }
                /**经销商省份*/
                params.put("channelProvince", channelBaseInfo.getChannelProvince());
                /**经销商城市*/
                params.put("channelCity", channelBaseInfo.getChannelCity());
                /**渠道归属*/
                if (ObjectUtils.isNotEmpty(channelBaseInfo)) {
                    params.put("channelBelong", channelBaseInfo.getChannelBelong());
                }
            }
        }

        /**---------------------------------     车辆信息     ----------------------------------**/
        CaseCarInfo caseCarInfo = caseCarInfoService.getOne(Wrappers.<CaseCarInfo>query().lambda()
                .eq(CaseCarInfo::getApplyNo, applyNo));
        if (ObjectUtils.isNotEmpty(caseCarInfo)) {
            /**车辆级别*/
            String carBodyClass = caseCarInfo.getCarBodyClass();
            params.put("carBodyClass", carBodyClass);
            /**车型*/
            String modelCode = caseCarInfo.getModelCode();
            params.put("modelCode", modelCode);

            /**---------------------------------     车辆详情     ----------------------------------**/
            CaseCarStyleDetail cartyleDetailInfo = carStyleDetailInfoService.getOne(Wrappers.<CaseCarStyleDetail>query().lambda()
                    .eq(CaseCarStyleDetail::getCarId, caseCarInfo.getId()));
            if (ObjectUtils.isNotEmpty(cartyleDetailInfo)) {
                /**是否新能源*/
                String isGreen = cartyleDetailInfo.getIsGreen();
                params.put("isGreen", isGreen);

                /** 资产主类*/
                String assetsClass = cartyleDetailInfo.getCarType();
                params.put("assetsClass", assetsClass);

                /** 资产子类*/
                String carTypeDetail = cartyleDetailInfo.getCarTypeDetail();
                params.put("carTypeDetail", carTypeDetail);
            }
        }

        BigDecimal contAmt = BigDecimal.ZERO;
        BigDecimal tailPayAmt = BigDecimal.ZERO;
        BigDecimal subsidyTotalAmt = BigDecimal.ZERO;

        /**  车款融资信息 车款 **/
        FinCostDetails carAmtCostInfoCar = caseCostInfoService.getOne(Wrappers.<FinCostDetails>query().lambda()
                .eq(FinCostDetails::getApplyNo, applyNo)
                .eq(FinCostDetails::getCostType, CostTypeEnum.CARAMT.getCode())
        );

        /**  车款融资信息 附加贷 **/
        FinCostDetails carAmtCostInfoAdd = caseCostInfoService.getOne(Wrappers.<FinCostDetails>query().lambda()
                .eq(FinCostDetails::getApplyNo, applyNo)
                .eq(FinCostDetails::getCostType, CostTypeEnum.AFFIXAMT.getCode())
        );
        if (ObjectUtils.isNotEmpty(carAmtCostInfoAdd)) {
            /** 附加贷金额*/
            BigDecimal loanAmt = null != carAmtCostInfoAdd.getLoanAmt() ? carAmtCostInfoAdd.getLoanAmt() : BigDecimal.ZERO;
            params.put("loanAmt", loanAmt.toString());
            contAmt = contAmt.add(loanAmt);
            tailPayAmt = contAmt.add(null != carAmtCostInfoAdd.getTailPayAmt() ? carAmtCostInfoAdd.getTailPayAmt() : BigDecimal.ZERO);
            subsidyTotalAmt = contAmt.add(null != carAmtCostInfoAdd.getDiscountAmt() ? carAmtCostInfoAdd.getDiscountAmt() : BigDecimal.ZERO);

            contAmt = contAmt.add(null != carAmtCostInfoAdd.getLoanAmt() ? carAmtCostInfoAdd.getLoanAmt() : BigDecimal.ZERO);
        }
        if (ObjectUtils.isNotEmpty(carAmtCostInfoCar)) {
            /**首付比例*/
            BigDecimal downPayScale = null != carAmtCostInfoCar.getDownPayScale() ? carAmtCostInfoCar.getDownPayScale() : BigDecimal.ZERO;
            params.put("downPayScale", downPayScale);

            /**还款方式*/
            String repayMode = carAmtCostInfoCar.getAlgorithmType();
            params.put("repayMode", repayMode);
        }
        /**贷款金额*/
        params.put("loanAmount", contAmt.toString());
        /**贴息金额*/
        params.put("tailPayAmt", tailPayAmt.toString());
        /**尾款金额*/
        params.put("subsidyTotalAmt", subsidyTotalAmt.toString());
        /** 角色+小程序进件*/

        /**反欺诈评分*/
        params.put("antiFraudGrade", 100);
        /**决策引擎评分*/
        params.put("decisionGrade", 100);
        runResult = RuleHelper.runRule(params, ruleId).getHit();
        return runResult;
    }

    /**
     * 通过规则id查询命中所有待激活池数据
     *
     * @param ruleId
     * @return
     */
    @Override
    public List<LoanActivateTrialVO> dealLoanActivatePoolByRule(String ruleId) {
        List<LoanActivateTrialVO> loanActivateTrialVOList = new ArrayList<>();
        List<LoanActivatePool> loanActivatePoolList = loanActivateService.list();
        int i = 0;
        if (!CollectionUtils.isEmpty(loanActivatePoolList)) {
            for (LoanActivatePool pool : loanActivatePoolList) {
                if (null != pool
                        && this.hitRules(pool.getApplyNo(), ruleId)) {
                    LoanActivateTrialVO loanActivateTrialVO = new LoanActivateTrialVO();
                    loanActivateTrialVO.setApplyNo(pool.getApplyNo());
                    CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
                            .eq(CaseBaseInfo::getApplyNo, pool.getApplyNo()));
                    loanActivateTrialVO.setCustName(caseBaseInfo.getCustNameRepeat());
                    loanActivateTrialVO.setBusinessType(caseBaseInfo.getBusinessType());
                    loanActivateTrialVO.setArea("");
                    loanActivateTrialVO.setDealer("");
                    loanActivateTrialVO.setLoanAmounts(caseCostInfoService
                            .costTotal(pool.getApplyNo()).getLoanAmt());
                    loanActivateTrialVOList.add(loanActivateTrialVO);
                    log.info("--------------命中第" + ++i + "条数据，编号【" + pool.getApplyNo() + "】--------------->");
                }
            }
        }
        return loanActivateTrialVOList;
    }

    /**
     * 通过规则id查询命中所有待激活池数据
     *
     * @return
     */
    @Override
    public IPage<LoanActivatePoolVO> newDealLoanActivatePoolByRule(Integer pageSize, Integer pageNumber) {
        List<LoanActivatePoolVO> list=new ArrayList();
//        Map<Long,List<String>> strMap = new HashMap<>();
//        LoanActivateCondition loanActivateCondition = new LoanActivateCondition();
        List<LoanActivatePoolVO> loanActivatePoolVOS=loanActivateService.getLoanActivateInfoLists();
        List<LoanActivateTrialVO> loanActivateTrialVOList = new ArrayList<>();
        loanActivatePoolVOS.stream().forEach(loanActivatePoolVO -> {
            JSONObject jsonObject=ruleAtomDataService.getCommonAtomRunParamsActive(loanActivatePoolVO.getContractNo());
            log.info("合同号码{}激活规则报文：{}",loanActivatePoolVO.getContractNo(),jsonObject);
            try{
                RuleRunResult ruleRunResult = RuleHelper.runByGroup(jsonObject, "activateRuleGroup", false, RuleRunEnum.PARALLEL, false);
                boolean isHit = ruleRunResult.getHit();
                log.info("放款激活规则组：{}=>执行结束，结果：{}", "activateRuleGroup", isHit);
                if (isHit) {
                    LoanActivateTrialVO loanActivateTrialVO = new LoanActivateTrialVO();
                    loanActivateTrialVO.setId(Long.parseLong(loanActivatePoolVO.getId()));
                    loanActivateTrialVO.setApplyNo(loanActivatePoolVO.getApplyNo());
                    CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
                            .eq(CaseBaseInfo::getApplyNo, loanActivatePoolVO.getApplyNo()));
                    loanActivateTrialVO.setCustName(caseBaseInfo.getCustNameRepeat());
                    loanActivateTrialVO.setBusinessType(caseBaseInfo.getBusinessType());
                    loanActivateTrialVO.setArea("");
                    loanActivateTrialVO.setDealer("");
                    loanActivateTrialVO.setLoanAmounts(caseCostInfoService
                            .costTotal(loanActivatePoolVO.getApplyNo()).getLoanAmt());
                    loanActivateTrialVOList.add(loanActivateTrialVO);
                }
            }catch (Exception e){
                log.info("放款激活规则组，{}:执行失败", "loanRisk");
            }
        });
        IPage  loanActivatePoolVOIPage = new Page();
        List result = new ArrayList();
        for(int i=0;i<pageSize;i++){
            result.add(loanActivateTrialVOList.get(pageSize*(pageNumber-1)+i));
        }
        loanActivatePoolVOIPage.setRecords(result);
        loanActivatePoolVOIPage.setTotal(loanActivateTrialVOList.size());
        loanActivatePoolVOIPage.setPages(pageNumber);
        loanActivatePoolVOIPage.setSize(pageSize);
        return loanActivatePoolVOIPage;
    }

    /**
     * @param
     * @description 通过业务规则id批量失效规则
     * @author yk.Li
     * @date 2020/7/6
     */
    @Override
    public void deActiveRuleByRuleNo(String[] ids) {
        //使规则失效
        for (String id : ids) {
            LoanActivateRules loanActivateRules = this.getById(id);
            if (null != loanActivateRules) {
                AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanActivateRules.getRulesId());
                if (null != afsRuleInfo) {
                    afsRuleInfoService.deActiveRule(afsRuleInfo.getId());//规则失效
                    log.info("--------------------规则【" + afsRuleInfo.getId() + "】已失效----------------->");
                }
            }
        }
    }

    /**
     * @param
     * @description 停用规则
     * @author yk.Li
     * @date 2020/7/6
     */
    public void deActiveRule(String id) {
        //设为停用
        LoanActivateRules loanActivateRules = this.getById(id);
        if (null != loanActivateRules) {
            loanActivateRules.setIsOpen(WhetherEnum.NO.getCode());
            loanActivateRules.setUneffectTime(new Date());
            this.updateById(loanActivateRules);
            //设置规则失效
            AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanActivateRules.getRulesId());
            if (null != afsRuleInfo) {
                afsRuleInfoService.deActiveRule(afsRuleInfo.getId());//规则失效
            }
        }
    }

    /**
     * @param
     * @description 启用规则
     * @author yk.Li
     * @date 2020/7/6
     */
    public void activeRule(@PathVariable String id) {
        //设为启用
        LoanActivateRules loanActivateRules = this.getById(id);
        if (null != loanActivateRules) {
            loanActivateRules.setIsOpen(WhetherEnum.YES.getCode());
            loanActivateRules.setEffectTime(new Date());
            this.updateById(loanActivateRules);
            //激活规则
            AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanActivateRules.getRulesId());
            if (null != afsRuleInfo) {
                afsRuleInfoService.activeRule(afsRuleInfo.getId());//规则生效
            }
        }
    }
}
